package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.RedisConst;
import com.itheima.dao.SetmealDao;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.pojo.Setmeal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    SetmealDao setmealDao;

    @Autowired
    JedisPool jedisPool;

    @Transactional
    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) {
        //1. 添加套餐（回显主键）
        setmealDao.add(setmeal);
        //2. 维护套餐和检查组的关系
        setRelation(setmeal, checkgroupIds);
        //3. 添加成功后，在redis中移除 图片名称
        jedisPool.getResource().srem(RedisConst.SETMEAL_PIC_RESOURCES, setmeal.getImg());
        //同步到redis中
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String string = objectMapper.writeValueAsString(setmeal);
            jedisPool.getResource().sadd("setmealList", setmeal.getId() + "-" + string);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        Page<Setmeal> pageSetmeal = setmealDao.findByCondition(queryPageBean.getQueryString());
        return new PageResult(pageSetmeal.getTotal(), pageSetmeal.getResult());
    }

    @Override
    public List<Setmeal> findAll() {
        List<Setmeal> setmealList = new ArrayList<>();
        Jedis jedis = jedisPool.getResource();
        ObjectMapper objectMapper = new ObjectMapper();
        //判断redis中是否有套餐
        if (jedis.exists("setmealList")) {
            Set<String> setmealListRD = jedis.smembers("setmealList");
            for (String s : setmealListRD) {
                String s1 = s.substring(3);
                try {
                    Setmeal setmeal = objectMapper.readValue(s1, Setmeal.class);
                    setmealList.add(setmeal);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //从数据库中取
            setmealList = setmealDao.findAll();
            //同步到redis中
            for (Setmeal setmeal : setmealList) {
                try {
                    String string = objectMapper.writeValueAsString(setmeal);
                    jedis.sadd("setmealList", setmeal.getId() + "-" + string);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        jedis.close();
        return setmealList;
    }

    @Override
    public Setmeal findDetailById(Integer id) {
        Setmeal setmeal = null;
        Jedis jedis = jedisPool.getResource();
        ObjectMapper objectMapper = new ObjectMapper();
        //判断redis中是否有套餐详情
        if (jedis.exists("setmealDetailsList")) {
            Set<String> setmealListRD = jedis.smembers("setmealDetailsList");
            for (String s : setmealListRD) {
                String[] split = s.split("-");
                if (id==Integer.parseInt(split[0])) {
                    String s1 = s.substring(3);
                    try {
                        setmeal=objectMapper.readValue(s1, Setmeal.class);
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                }
            }
            if (setmeal == null) {
                //从数据库中取
                setmeal = setmealDao.findDetailById(id);
                //同步到redis中
                try {
                    String string = objectMapper.writeValueAsString(setmeal);
                    jedis.sadd("setmealDetailsList", setmeal.getId() + "-" + string);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //从数据库中取
            setmeal = setmealDao.findDetailById(id);
            //同步到redis中
            try {
                String string = objectMapper.writeValueAsString(setmeal);
                jedis.sadd("setmealDetailsList", setmeal.getId() + "-" + string);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        jedis.close();
        return setmeal;
    }

    @Override
    public Setmeal findById(Integer id) {
        return setmealDao.findById(id);
    }

    @Override
    public List<Map> getSetmealReport() {
        return setmealDao.getSetmealReport();
    }

    @Override
    public List<Integer> findCheckGroupIdsBySetMealId(Integer id) {
        return setmealDao.findCheckGroupIdsBySetMealId(id);
    }

    @Override
    public void update(Integer[] checkgroupIds, Setmeal setmeal) {
        //判断图片是否已被修改
        Setmeal setmeal1DB = setmealDao.findById(setmeal.getId());
        //如果被修改过,将图片名称存入redis中,交给定时任务进行删除
        if (!(setmeal1DB.getImg().equals(setmeal.getImg()))) {
            jedisPool.getResource().sadd(RedisConst.SETMEAL_PIC_RESOURCES, setmeal1DB.getImg());
        }
        setmealDao.update(setmeal);
        setmealDao.deleteRelation(setmeal.getId());
        setRelation(setmeal, checkgroupIds);
        //编辑成功,将redis中的图片名称删除
        jedisPool.getResource().srem(RedisConst.SETMEAL_PIC_RESOURCES, setmeal.getImg());
        //更新redis中的数据
        //更新套餐列表
        Jedis jedis = jedisPool.getResource();
        ObjectMapper objectMapper = new ObjectMapper();
        Set<String> setmealListRD = jedis.smembers("setmealList");
        for (String s : setmealListRD) {
            String[] split = s.split("-");
            if (setmeal.getId()==Integer.parseInt(split[0])) {
                //先删除在重新添加
                jedis.srem("setmealList", s);
                try {
                    String string = objectMapper.writeValueAsString(setmeal);
                    jedis.sadd("setmealList", setmeal.getId() + "-" + string);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            }
        }
        //更新套餐详情列表
        //直接删除
        Set<String> setmealDetailsListRD = jedis.smembers("setmealDetailsList");
        for (String s : setmealDetailsListRD) {
            String[] split = s.split("-");
            if (setmeal.getId()==Integer.parseInt(split[0])) {
                jedis.srem("setmealDetailsList", s);
            }
        }
    }

    @Override
    public void deleteById(Integer id) {
        Setmeal setmeal1DB = setmealDao.findById(id);
        jedisPool.getResource().sadd(RedisConst.SETMEAL_PIC_RESOURCES, setmeal1DB.getImg());
        setmealDao.deleteRelation(id);
        setmealDao.deleteById(id);
        //更新redis中的数据
        //更新套餐列表
        Jedis jedis = jedisPool.getResource();
        ObjectMapper objectMapper = new ObjectMapper();
        Set<String> setmealListRD = jedis.smembers("setmealList");
        for (String s : setmealListRD) {
            String[] split = s.split("-");
            if (id==Integer.parseInt(split[0])) {
                //先删除在重新添加
                jedis.srem("setmealList", s);
            }
        }
        //更新套餐详情列表
        //直接删除
        Set<String> setmealDetailsListRD = jedis.smembers("setmealDetailsList");
        for (String s : setmealDetailsListRD) {
            String[] split = s.split("-");
            if (id==Integer.parseInt(split[0])) {
                jedis.srem("setmealDetailsList", s);
            }
        }
    }

    /**
     * 设置检查组和套餐的关系
     *
     * @param setmeal
     * @param checkgroupIds
     */
    private void setRelation(Setmeal setmeal, Integer[] checkgroupIds) {
        if (setmeal.getId() != null && checkgroupIds != null && checkgroupIds.length > 0) {
            for (Integer checkgroupId : checkgroupIds) {
                setmealDao.setRelation(setmeal.getId(), checkgroupId);
            }
        }
    }
}
